package Controller

import (
	"back_go/Common/ProdPropRule"
	"back_go/DAO/gorm"
	"back_go/DAO/gorm/GormModel"
	"back_go/Response"
	"back_go/Util"
	"fmt"
	"github.com/gin-gonic/gin"
	"log"
	"math"
	"strconv"
	"time"
)

func GetSpecList(c *gin.Context) {
	var list []GormModel.TzProdProp
	db := gorm.Db
	err := db.Where("rule = ?", ProdPropRule.SPEC).Find(&list).Error
	if err != nil {
		log.Println(err)
		c.JSON(200, Response.ResponseBody{
			Code:      "A00005",
			Msg:       "服务器出了点小差",
			Data:      nil,
			Version:   "v1.0",
			Timestamp: time.Now().Unix(),
			Sign:      nil,
			Success:   false,
			Fail:      false,
		})
		return
	}
	c.JSON(200, Response.ResponseBody{
		Code:      "00000",
		Msg:       nil,
		Data:      list,
		Version:   "v1.0",
		Timestamp: time.Now().Unix(),
		Sign:      nil,
		Success:   true,
		Fail:      false,
	})
}

func InfoGetListSpecMaxValueId(c *gin.Context) {
	var prodPropValue *GormModel.TzProdPropValue
	db := gorm.Db
	db.Order("value_id DESC").Limit(1).Find(&prodPropValue)
	if prodPropValue != nil {
		c.JSON(200, Response.ResponseBody{
			Code:      "00000",
			Msg:       nil,
			Data:      prodPropValue.ValueID,
			Version:   "v1.0",
			Timestamp: time.Now().Unix(),
			Sign:      nil,
			Success:   true,
			Fail:      false,
		})
		return
	}
	c.JSON(200, Response.ResponseBody{
		Code:      "00000",
		Msg:       nil,
		Data:      0,
		Version:   "v1.0",
		Timestamp: time.Now().Unix(),
		Sign:      nil,
		Success:   true,
		Fail:      false,
	})
}

func GetListSpecValue(c *gin.Context) {
	specIdStr := c.Param("specId")
	specId, err := strconv.Atoi(specIdStr)
	if err != nil {
		c.JSON(200, Response.ResponseBody{
			Code:      "A00005",
			Msg:       "服务器出了点小差",
			Data:      nil,
			Version:   "v1.0",
			Timestamp: time.Now().Unix(),
			Sign:      nil,
			Success:   false,
			Fail:      false,
		})
		return
	}
	db := gorm.Db
	var list []GormModel.TzProdPropValue
	db.Where("prop_id =?", specId).Find(&list)
	c.JSON(200, Response.ResponseBody{
		Code:      "00000",
		Msg:       nil,
		Data:      list,
		Version:   "v1.0",
		Timestamp: time.Now().Unix(),
		Sign:      nil,
		Success:   true,
		Fail:      false,
	})
}

func GetProdSpecByPage(c *gin.Context) {
	currentStr := c.Query("current")
	sizeStr := c.Query("size")

	// 将字符串类型的分页参数转换为整数
	current, err := strconv.Atoi(currentStr)
	if err != nil {
		current = 1 // 默认当前页为 1
	}
	size, err := strconv.Atoi(sizeStr)
	if err != nil {
		size = 10 // 默认每页显示 10 条记录
	}

	// 绑定查询参数到 TzProdProp 结构体
	var prodProp GormModel.TzProdProp
	_ = c.ShouldBindQuery(&prodProp)
	prodProp.Rule = ProdPropRule.SPEC.Value()
	prodProp.ShopID = 1 // 暂时写死
	db := gorm.Db

	// 构建查询
	query := db.Table("tz_prod_prop").
		Select("tz_prod_prop.*, tz_prod_prop_value.value_id, tz_prod_prop_value.prop_value").
		Joins("LEFT JOIN tz_prod_prop_value ON tz_prod_prop.prop_id = tz_prod_prop_value.prop_id").
		Where("tz_prod_prop.rule = ?", prodProp.Rule).
		Where("tz_prod_prop.shop_id = ?", prodProp.ShopID)

	// 计算偏移量
	offset := (current - 1) * size

	// 执行分页查询
	var results []struct {
		GormModel.TzProdProp
		ValueID   int64  `json:"valueId"`
		PropValue string `json:"propValue"`
	}
	var total int64
	if err := query.Count(&total).Error; err != nil {
		c.JSON(200, Response.ResponseBody{
			Code:      "A00005",
			Data:      nil,
			Msg:       "服务器出了问题",
			Version:   "1.0",
			Timestamp: time.Now().Unix(),
			Sign:      "",
			Fail:      true,
			Success:   false,
		})
		return
	}
	if err := query.Offset(offset).Limit(size).Find(&results).Error; err != nil {
		c.JSON(200, Response.ResponseBody{
			Code:      "A00005",
			Data:      nil,
			Msg:       "服务器出了问题",
			Version:   "1.0",
			Timestamp: time.Now().Unix(),
			Sign:      "",
			Fail:      true,
			Success:   false,
		})
		return
	}

	// 处理查询结果，将关联的属性值分组到对应的属性中
	prodPropsMap := make(map[int64]*GormModel.TzProdProp)
	for _, result := range results {
		propID := result.PropID
		if _, exists := prodPropsMap[propID]; !exists {
			prodPropsMap[propID] = &GormModel.TzProdProp{
				PropID:   result.PropID,
				PropName: result.PropName,
				Rule:     result.Rule,
				ShopID:   result.ShopID,
			}
		}
		if result.ValueID != 0 {
			prodPropsMap[propID].ProdPropValues = append(prodPropsMap[propID].ProdPropValues, GormModel.TzProdPropValue{
				ValueID:   result.ValueID,
				PropValue: result.PropValue,
				PropID:    propID,
			})
		}
	}

	// 将 map 中的结果转换为切片
	var prodProps []GormModel.TzProdProp
	for _, prop := range prodPropsMap {
		prodProps = append(prodProps, *prop)
	}

	// 返回分页结果
	c.JSON(200, Response.ResponseBody{
		Code: "00000",
		Data: PageParam1[GormModel.TzProdProp]{
			Current: current,
			Total:   total,
			Size:    size,
			Records: prodProps,
			Pages:   int(math.Ceil(float64(total) / float64(size))),
		},
		Msg:       nil,
		Success:   true,
		Fail:      false,
		Version:   "1.0",
		Timestamp: time.Now().Unix(),
		Sign:      "",
	})
}

func UpdateSpec(c *gin.Context) {
	var prodProp GormModel.TzProdProp
	_ = c.ShouldBindJSON(&prodProp)
	prodProp.Rule = ProdPropRule.SPEC.Value()
	prodProp.ShopID = 1
	db := gorm.Db.Begin()
	var err error
	defer func() {
		if r := recover(); r != nil {
			db.Rollback()
			c.JSON(200, Response.ResponseBody{
				Code:    "A00005",
				Data:    nil,
				Success: true,
				Msg:     "服务器出了点小差",
			})
		} else if err != nil {
			db.Rollback()
		} else {
			db.Commit()
		}
	}()
	err = updateSec(prodProp)
	c.JSON(200, Response.ResponseBody{
		Code:      "00000",
		Data:      true,
		Msg:       nil,
		Version:   "1.0",
		Timestamp: time.Now().Unix(),
		Sign:      "",
		Fail:      false,
		Success:   true,
	})
}

func SaveSpec(c *gin.Context) {
	var prodProp GormModel.TzProdProp
	_ = c.ShouldBindJSON(&prodProp)
	prodProp.Rule = ProdPropRule.SPEC.Value()
	prodProp.ShopID = 1
	db := gorm.Db.Begin()
	var err error
	defer func() {
		if r := recover(); r != nil {
			db.Rollback()
			c.JSON(200, Response.ResponseBody{
				Code:    "A00005",
				Data:    nil,
				Success: true,
				Msg:     "服务器出了点小差",
			})
		} else if err != nil {
			db.Rollback()
		} else {
			db.Commit()
		}
	}()
	err = saveSec(prodProp)
	c.JSON(200, Response.ResponseBody{
		Code:      "00000",
		Data:      true,
		Msg:       nil,
		Version:   "1.0",
		Timestamp: time.Now().Unix(),
		Sign:      "",
		Fail:      false,
		Success:   true,
	})
}

func DelSpec(c *gin.Context) {
	idStr := c.Param("")
	var err error
	id, err := strconv.ParseInt(idStr, 10, 64)
	db := gorm.Db.Begin()

	defer func() {
		if r := recover(); r != nil {
			db.Rollback()
			c.JSON(200, Response.ResponseBody{
				Code:    "A00005",
				Data:    nil,
				Success: true,
				Msg:     "服务器出了点小差",
			})
		} else if err != nil {
			db.Rollback()
		} else {
			db.Commit()
		}
	}()
	err = delSec(id, 1, ProdPropRule.SPEC.Value())
	c.JSON(200, Response.ResponseBody{
		Code:      "00000",
		Data:      true,
		Msg:       nil,
		Version:   "1.0",
		Timestamp: time.Now().Unix(),
		Sign:      "",
		Fail:      false,
		Success:   true,
	})
}

func updateSec(prodProp GormModel.TzProdProp) error {
	var dbProdProp *GormModel.TzProdProp
	db := gorm.Db.Begin()
	var err error
	defer func() {
		if r := recover(); r != nil {
			db.Rollback()

		} else if err != nil {
			db.Rollback()
		} else {
			db.Commit()
		}
	}()
	err = db.Where("prop_id =?", prodProp.PropID).Where("shop_id", prodProp.ShopID).
		Where("rule", prodProp.Rule).Find(&dbProdProp).Error
	if dbProdProp != nil && prodProp.PropID != dbProdProp.PropID {
		return fmt.Errorf("已有相同名称规格")
	}
	db.Save(&prodProp)
	// 先删除原有的属性值，再添加新的属性值
	//delete from tz_prod_prop_value where prop_id = #{propId}
	db.Where("prop_id =?", prodProp.PropID).Delete(&GormModel.TzProdPropValue{})
	if Util.SliceIsEmpty(prodProp.ProdPropValues) {
		return nil
	}

	for i := range prodProp.ProdPropValues {
		prodProp.ProdPropValues[i].PropID = prodProp.PropID
	}

	// 批量插入 TzProdPropValue 记录
	result := db.Create(&prodProp.ProdPropValues).Error
	if result != nil {
		return result
	}
	return nil
}
func saveSec(prodProp GormModel.TzProdProp) error {
	var dbProdProp *GormModel.TzProdProp
	db := gorm.Db.Begin()
	var err error
	defer func() {
		if r := recover(); r != nil {
			db.Rollback()

		} else if err != nil {
			db.Rollback()
		} else {
			db.Commit()
		}
	}()
	err = db.Where("prop_id =?", prodProp.PropID).Where("shop_id", prodProp.ShopID).
		Where("rule", prodProp.Rule).Find(&dbProdProp).Error
	if dbProdProp != nil && prodProp.PropID != dbProdProp.PropID {
		return fmt.Errorf("已有相同名称规格")
	}
	db.Save(&prodProp)

	if Util.SliceIsEmpty(prodProp.ProdPropValues) {
		return nil
	}

	for i := range prodProp.ProdPropValues {
		prodProp.ProdPropValues[i].PropID = prodProp.PropID
	}

	// 批量插入 TzProdPropValue 记录
	result := db.Create(&prodProp.ProdPropValues).Error
	if result != nil {
		return result
	}
	return nil
}
func delSec(prodId int64, shopId int64, propRule int) error {
	db := gorm.Db.Begin()
	var err error
	defer func() {
		if r := recover(); r != nil {
			db.Rollback()

		} else if err != nil {
			db.Rollback()
		} else {
			db.Commit()
		}
	}()
	result := db.Where("prop_id =?", prodId).Where("shop_id", shopId).
		Where("rule", propRule).Delete(&GormModel.TzProdProp{})
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return nil
	}
	// 删除原有的属性值
	db.Where("prop_id =?", prodId).Delete(&GormModel.TzProdPropValue{})
	if propRule == ProdPropRule.ATTRIBUTE.Value() {
		db.Where("prop_id =?", prodId).Delete(&GormModel.TzCategoryProp{})
	}
	return nil
}
